package com.zone.vehicle.superapp.model;

import android.content.Context;
import android.util.Log;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.alibaba.fastjson.JSON;
import com.zone.sdk.common.http.base.Result;
import com.zone.sdk.common.http.callback.ResultCallBack;
import com.zone.sdk.module.account.entity.CaptchaCertExchangeEntity;
import com.zone.sdk.module.account.entity.CaptchaGetEntity;
import com.zone.sdk.module.account.entity.CaptchaPointEntity;
import com.zone.sdk.module.account.entity.CheckCaptchaEntity;
import com.zone.sdk.module.account.entity.LoginEntity;
import com.zone.sdk.module.account.entity.LoginStatusEntity;
import com.zone.sdk.module.account.entity.QrLoginEntity;
import com.zone.sdk.module.account.entity.QrLoginPollEntity;
import com.zone.sdk.module.account.entity.UserInfoEntity;
import com.zone.sdk.module.account.request.UserInfoRequest;
import com.zone.sdk.module.account.response.CaptchaGetResponse;
import com.zone.sdk_api.ApiManager;
import com.zone.sdk_api.common.Content;
import com.zone.vehicle.superapp.repository.LoginRepository;
import com.zone.vehicle.superapp.utils.SharedPreferencesUtil;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import static com.zone.sdk.common.http.Content.AUTHORIZATION_ACCOUNT;
import static com.zone.sdk.common.http.Content.AUTHORIZATION_ACCOUNT_BEARER;
import static com.zone.sdk_api.common.Content.USER_ID;
import static com.zone.sdk_api.common.Content.VIN_TEST;
import static com.zone.vehicle.superapp.common.ContentAccount.ACCESS_TOKEN;
import static com.zone.vehicle.superapp.common.ContentAccount.ACCESS_TOKEN_EXP;
import static com.zone.vehicle.superapp.common.ContentAccount.FIRST_LOGIN;
import static com.zone.vehicle.superapp.common.ContentAccount.LOGIN;
import static com.zone.vehicle.superapp.common.ContentAccount.REFRESH_TOKEN;
import static com.zone.vehicle.superapp.common.ContentAccount.REFRESH_TOKEN_EXP;

public class LoginViewModel extends ViewModel {

    private static final String TAG = LoginViewModel.class.getSimpleName();

    private final MutableLiveData<QrLoginEntity> qrCode = new MutableLiveData<>();
    private final MutableLiveData<QrLoginPollEntity> qrLoginPollEntity = new MutableLiveData<>();
    private final MutableLiveData<Result> error = new MutableLiveData<>();
    private final MutableLiveData<String> phone = new MutableLiveData<>();
    private final MutableLiveData<Long> refreshCodeTime = new MutableLiveData<>();
    private final MutableLiveData<CaptchaGetEntity> captchaGet = new MutableLiveData<>();
    private final MutableLiveData<CheckCaptchaEntity> checkCaptcha = new MutableLiveData<>();
    private final MutableLiveData<String> captcha_certificate = new MutableLiveData<>();
    private final MutableLiveData<LoginEntity> loginEntity = new MutableLiveData<>();
    private final LoginRepository loginRepository;


    private final MutableLiveData<Result> modifyPwdResult = new MutableLiveData<>();
    private final MutableLiveData<Result> updateUserInfoResult = new MutableLiveData<>();
    //手机扫码登录状态
    private final MutableLiveData<LoginStatusEntity> loginStatusEntityMutableLiveData = new MutableLiveData<>();
    private final MutableLiveData<UserInfoEntity> userInfo = new MutableLiveData<>();

    public MutableLiveData<QrLoginEntity> getQrCode() {
        return qrCode;
    }

    public MutableLiveData<Result> getError() {
        return error;
    }

    public MutableLiveData<String> getPhone() {
        return phone;
    }

    public MutableLiveData<CaptchaGetEntity> getCaptchaGet() {
        return captchaGet;
    }

    public MutableLiveData<QrLoginPollEntity> getQrLoginPollEntity() {
        return qrLoginPollEntity;
    }

    public MutableLiveData<CheckCaptchaEntity> getCheckCaptcha() {
        return checkCaptcha;
    }

    public MutableLiveData<LoginEntity> getLoginEntity() {
        return loginEntity;
    }

    public MutableLiveData<String> getCaptcha_certificate() {
        return captcha_certificate;
    }

    public MutableLiveData<Result> getModifyPwdResult() {
        return modifyPwdResult;
    }

    public MutableLiveData<Result> getUpdateUserInfoResult() {
        return updateUserInfoResult;
    }

    public MutableLiveData<UserInfoEntity> getUserInfo() {
        return userInfo;
    }

    public MutableLiveData<LoginStatusEntity> getLoginStatusEntityMutableLiveData() {
        return loginStatusEntityMutableLiveData;
    }

    LoginViewModel(LoginRepository loginRepository) {
        this.loginRepository = loginRepository;
    }

    /**
     * 获取扫码登录二维码
     */
    public void getRemoteQrCode(Context context){
        String vin = SharedPreferencesUtil.getInstance(context).getSP(Content.VIN);
        loginRepository.getQrCode(vin, new ResultCallBack<Result<QrLoginEntity>>() {
            @Override
            public void onSuccess(Result<QrLoginEntity> qrLoginEntityResult) {
                if (qrLoginEntityResult.getCode() == 200){
                    QrLoginEntity qrLoginEntity = qrLoginEntityResult.getData();
                    String codeId = qrLoginEntity.getLogin_url().substring(qrLoginEntity.getLogin_url().indexOf("code_id=")+8);
                    qrLoginEntity.setCodeId(codeId);
                }else {
                    buildError(""+qrLoginEntityResult.getCode(), qrLoginEntityResult.getResultMsg());
                }
                qrCode.setValue(qrLoginEntityResult.getData());
            }

            @Override
            public void onError(String errorCode, String message) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void qrLoginPolling(){
        if (ObjectUtils.isEmpty(qrCode.getValue())){
            return;
        }
        loginRepository.qrLoginPolling(qrCode.getValue().getCodeId(), new ResultCallBack<Result<QrLoginPollEntity>>() {
            @Override
            public void onSuccess(Result<QrLoginPollEntity> result) {
                if (result.getCode() == 200) {
                    if (result.getData().getStatus() == 3) {
                        qrLoginPollEntity.setValue(result.getData());
                    }
                }else {
                    buildError(""+result.getCode(), result.getResultMsg());
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                buildError(errorCode, message);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    /**
     * 获取三方秘钥
     */
    public void captchaGet(){
        loginRepository.captchaGet(new ResultCallBack<CaptchaGetResponse<CaptchaGetEntity>>() {
            @Override
            public void onSuccess(CaptchaGetResponse<CaptchaGetEntity> captchaGetEntityCaptchaGetResponse) {
//                Log.d(TAG, "captchaGet onSuccess:"+captchaGetEntityCaptchaGetResponse.toString());
                captchaGet.setValue(captchaGetEntityCaptchaGetResponse.getRepData());
            }

            @Override
            public void onError(String errorCode, String message) {
                Log.d(TAG, "captchaGet onError errorCode:"+errorCode+" message:"+message);
                buildError(errorCode, message);
                captchaGet.setValue(null);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    private void buildError(String errorCode, String message) {
        Result result = new Result();
        result.setResultCode(errorCode);
        result.setResultMsg(message);
        error.setValue(result);
    }

    /**
     * 三方安全校验
     */
    public void checkCaptcha(double sliderXMoved, String token, String key){
        Log.d(TAG, "getRemoteCode:");
        final CaptchaGetEntity captchaGetEntity = captchaGet.getValue();
        if (ObjectUtils.isNotEmpty(captchaGetEntity)){
            CaptchaPointEntity point = new CaptchaPointEntity();
            point.setX(5);
            point.setY(sliderXMoved);
            captchaGetEntity.setPoint(point);
//            captchaGet.setValue(captchaGetEntity);
        }
        loginRepository.checkCaptcha(sliderXMoved, token, key, new ResultCallBack<CaptchaGetResponse<CheckCaptchaEntity>>() {
            @Override
            public void onSuccess(CaptchaGetResponse<CheckCaptchaEntity> checkCaptchaEntityResult) {
                if (!(checkCaptchaEntityResult.getRepCode().equals("200")
                     || checkCaptchaEntityResult.getRepCode().equals("0000"))) {
                    buildError(checkCaptchaEntityResult.getRepCode(), checkCaptchaEntityResult.getRepMsg());
                    checkCaptcha.setValue(null);
                }else {
                    checkCaptcha.setValue(checkCaptchaEntityResult.getRepData());
                    captchaCertExchange(captchaGetEntity,  phone.getValue());
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                buildError(errorCode, message);
                checkCaptcha.setValue(null);
//                captchaGet.setValue(null);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void captchaCertExchange(CaptchaGetEntity captchaGetEntity, String phone){
        if (ObjectUtils.isEmpty(captchaGetEntity)){
            return;
        }
        loginRepository.captchacertExchange(captchaGetEntity.getToken(), captchaGetEntity.getPoint().getY(), captchaGetEntity.getSecretKey(), new ResultCallBack<Result<CaptchaCertExchangeEntity>>() {
            @Override
            public void onSuccess(Result<CaptchaCertExchangeEntity> result) {
                if (result.getCode() == 200){
                    captcha_certificate.setValue(result.getData().getCaptcha_certificate());
//                    ApiManager.getInstance().setHeader(Content.X_DEVICE_FROM, entity.getData().getCaptcha_certificate());
//                    loginPhoneCode(phone, entity.getData().getCaptcha_certificate());
                }else {
                    buildError(""+result.getCode(), result.getResultMsg());
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                buildError(errorCode, message);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void loginPhoneCode(Context context, String phone, String captcha_certificate){
        loginRepository.loginPhoneCode(phone, captcha_certificate, new ResultCallBack<Result<LoginEntity>>() {
            @Override
            public void onSuccess(Result<LoginEntity> result) {
                if (result.getCode() == 200) {
                    refreshCodeTime.setValue(System.currentTimeMillis());
                    loginEntity.setValue(result.getData());
                    cacheLogin(context, result.getData());
                    queryUserInfo(context);
                }else {
                    buildError(""+result.getCode(), result.getResultMsg());
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                buildError(errorCode, message);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void loginPhoneCodeCheck(Context context, String phone, String phone_code){
        loginRepository.loginPhoneCodeCheck(phone, captcha_certificate.getValue(), phone_code, new ResultCallBack<Result<LoginEntity>>() {
            @Override
            public void onSuccess(Result<LoginEntity> result) {
                if (result.getCode() == 200){
                    loginEntity.setValue(result.getData());
                    cacheLogin(context, result.getData());
                    queryUserInfo(context);
//                    SharedPreferencesUtil.getInstance(context).setObject(Content.LOGIN, result.getData());
//                    ApiManager.getInstance().setHeader(AUTHORIZATION_ACCOUNT, AUTHORIZATION_APPSTORE_BEARER+result.getData().getAccess_token());
                }else {
                    buildError(""+result.getCode(), result.getResultMsg());
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                buildError(errorCode, message);
            }

            @Override
            public void onComplete() {

            }
        });
    }

    //设置密码
    public void userPwdModify(Context context, String pwd){
        loginRepository.userPwdModify(pwd, new ResultCallBack<Result>() {
            @Override
            public void onSuccess(Result result) {
                if (result.getCode() == 200){
                    modifyPwdResult.setValue(result);
                    queryUserInfo(context);
                }else {
                    buildError(""+result.getCode(), result.getResultMsg());
                }
            }

            @Override
            public void onError(String errorCode, String message) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void loginStatus(){
        loginRepository.loginStatus(new ResultCallBack<Result<LoginStatusEntity>>() {
            @Override
            public void onSuccess(Result<LoginStatusEntity> loginStatusEntityResult) {
                loginStatusEntityMutableLiveData.setValue(loginStatusEntityResult.getData());
            }

            @Override
            public void onError(String errorCode, String message) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void login(Context context, String username, String password) {
        loginRepository.login(username, password, captcha_certificate.getValue(), new ResultCallBack<Result<LoginEntity>>() {
            @Override
            public void onSuccess(Result<LoginEntity> result) {
                if (result.getCode() == 200){
                    LoginEntity login = result.getData();
                    cacheLogin(context, login);
//                    SharedPreferencesUtil.getInstance(context).setObject(Content.LOGIN, result.getData());
//                    ApiManager.getInstance().setHeader(AUTHORIZATION_ACCOUNT, AUTHORIZATION_ACCOUNT_BEARER +result.getData().getAccess_token());
                    loginEntity.setValue(login);
                }else {
                    buildError(result.getResultCode(), result.getResultMsg());
                }
            }

            @Override
            public void onError(String errorCode, String message) {
                buildError(errorCode, message);
            }

            @Override
            public void onComplete() {
            }
        });
    }

    private void cacheLogin(Context context, LoginEntity login){
        Log.d(TAG, "loginInfo=" + JSON.toJSONString(login));
        if (ObjectUtils.isNotEmpty(login)) {
            SharedPreferencesUtil.getInstance(context).setObject(Content.LOGIN, login);
            String access_token = login.getAccess_token();
            if (StringUtils.isNotEmpty(access_token)) {
                Log.d(TAG, "set header access_token="+access_token);
                ApiManager.getInstance().setHeader(AUTHORIZATION_ACCOUNT, AUTHORIZATION_ACCOUNT_BEARER + access_token);
            }
            SharedPreferencesUtil.getInstance(context).setObject(LOGIN, login);
            SharedPreferencesUtil.getInstance(context).putSP(ACCESS_TOKEN, login.getAccess_token());
            SharedPreferencesUtil.getInstance(context).putSP(REFRESH_TOKEN, login.getRefresh_token());
            SharedPreferencesUtil.getInstance(context).putSP(ACCESS_TOKEN_EXP, String.valueOf(login.getAccess_token_exp()));
            SharedPreferencesUtil.getInstance(context).putSP(REFRESH_TOKEN_EXP, String.valueOf(login.getRefresh_token_exp()));
            SharedPreferencesUtil.getInstance(context).putSP(FIRST_LOGIN, String.valueOf(login.getFirst_login()));
        }
    }

    public void cacheLogin(Context context, QrLoginPollEntity.Token token){
        Log.d(TAG, "loginInfo="+ JSON.toJSONString(token));
        if (ObjectUtils.isNotEmpty(token)) {
            String access_token = token.getAccess_token();
            if (StringUtils.isNotEmpty(access_token)) {
                Log.d(TAG, "set header access_token="+access_token);
                ApiManager.getInstance().setHeader(AUTHORIZATION_ACCOUNT, AUTHORIZATION_ACCOUNT_BEARER + access_token);
            }
//            ApiManager.getInstance().setHeader(AUTHORIZATION_ACCOUNT, AUTHORIZATION_ACCOUNT_BEARER +token.getAccess_token());
            SharedPreferencesUtil.getInstance(context).putSP(ACCESS_TOKEN, token.getAccess_token());
            SharedPreferencesUtil.getInstance(context).putSP(REFRESH_TOKEN, token.getRefresh_token());
            SharedPreferencesUtil.getInstance(context).putSP(ACCESS_TOKEN_EXP, String.valueOf(token.getAccess_token_exp()));
            SharedPreferencesUtil.getInstance(context).putSP(REFRESH_TOKEN_EXP, String.valueOf(token.getRefresh_token_exp()));
        }
    }

    public void clearCache(Context context){
        SharedPreferencesUtil.getInstance(context).removeSP(Content.LOGIN);
        SharedPreferencesUtil.getInstance(context).removeSP(Content.USER_INFO);
        SharedPreferencesUtil.getInstance(context).removeSP(Content.ACCESS_TOKEN);
        SharedPreferencesUtil.getInstance(context).removeSP(Content.REFRESH_TOKEN);
        SharedPreferencesUtil.getInstance(context).removeSP(Content.ACCESS_TOKEN_EXP);
        SharedPreferencesUtil.getInstance(context).removeSP(Content.REFRESH_TOKEN_EXP);
        SharedPreferencesUtil.getInstance(context).removeSP(Content.FIRST_LOGIN);
    }

    public void queryUserInfo(Context context) {
        String ACCESS_TOKEN = SharedPreferencesUtil.getInstance(context).getSP(Content.ACCESS_TOKEN);
        if (StringUtils.isEmpty(ACCESS_TOKEN)){
            Log.e(TAG, "queryUserInfo ACCESS_TOKEN is null");
            return;
        }
        Log.e(TAG, "queryUserInfo ACCESS_TOKEN ="+ACCESS_TOKEN);
        loginRepository.queryUserInfo(new ResultCallBack<Result<UserInfoEntity>>() {
            @Override
            public void onSuccess(Result<UserInfoEntity> result) {
                if (result.getCode() == 200){
                    UserInfoEntity userInfoEntity = result.getData();
                    userInfo.setValue(userInfoEntity);
                    Log.d(TAG, "userInfo="+ JSON.toJSONString(userInfoEntity));
                    SharedPreferencesUtil.getInstance(context).setObject(Content.USER_INFO, userInfoEntity);
                    SharedPreferencesUtil.getInstance(context).putSP(USER_ID, String.valueOf(userInfoEntity.getId()));
                }else {
                    buildError(""+result.getCode(), result.getResultMsg());
                }
            }

            @Override
            public void onError(String errorCode, String message) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void updateUserInfo(UserInfoRequest request) {
        loginRepository.updateUserInfo(request, new ResultCallBack<Result>() {
            @Override
            public void onSuccess(Result result) {
                updateUserInfoResult.setValue(result);
            }

            @Override
            public void onError(String errorCode, String message) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    public void logout(Context context){
        String access_token = SharedPreferencesUtil.getInstance(context).getSP(Content.ACCESS_TOKEN);
        String refresh_token = SharedPreferencesUtil.getInstance(context).getSP(Content.REFRESH_TOKEN);
        Log.d(TAG, "access_token="+ JSON.toJSONString(access_token)+" refresh_token="+refresh_token);
        if (StringUtils.isNotEmpty(access_token) && StringUtils.isNotEmpty(refresh_token)) {
            ApiManager.getInstance().setHeader(AUTHORIZATION_ACCOUNT, AUTHORIZATION_ACCOUNT_BEARER + access_token);
            loginRepository.logout(refresh_token, new ResultCallBack<Result>() {
                @Override
                public void onSuccess(Result result) {
                    if (result.getCode() == 200) {
                        loginEntity.setValue(null);
                        clearCache(context);
                    } else {
                        buildError("" + result.getCode(), result.getResultMsg());
                    }
                }

                @Override
                public void onError(String errorCode, String message) {
                }

                @Override
                public void onComplete() {
                }
            });
        }
        clearCache(context);
//        loginEntity.setValue(null);
//        SharedPreferencesUtil.getInstance(context).removeSP(Content.LOGIN);
//        SharedPreferencesUtil.getInstance(context).removeSP(Content.USER_INFO);
//        SharedPreferencesUtil.getInstance(context).removeSP(Content.ACCESS_TOKEN);
//        SharedPreferencesUtil.getInstance(context).removeSP(Content.REFRESH_TOKEN);
//        SharedPreferencesUtil.getInstance(context).removeSP(Content.ACCESS_TOKEN_EXP);
//        SharedPreferencesUtil.getInstance(context).removeSP(Content.REFRESH_TOKEN_EXP);
//        SharedPreferencesUtil.getInstance(context).removeSP(Content.FIRST_LOGIN);
    }

}